(function(global){
    /**
     * 数据存储类。
     * @constructor
     * @param key {String} 存储主键, 默认是id.
     * @param dataAdapter {DataAdapter|Function}
     */
    var Store = function Store(key, dataAdapter, updateDataAdapter){
        Observable.enable(this);
        //兼容 new Store(dataAdapter)调用方式.
        if(arguments.length < 2 && !Type.isString(key)){            
            dataAdapter = key;
            key = 'id';
        }
        //key默认为 id.
        this.key = key || 'id';
        //数据适配器处理.
        dataAdapter = dataAdapter || DataAdapter.emptyDataAdapter;        
        if(Type.isFunction(dataAdapter)){
            if(dataAdapter.superFunction !== DataAdapter){
                var dataAdapterFun = dataAdapter;
                dataAdapter = new DataAdapter(dataAdapterFun);    
            } else {
                var dataAdapterConstructor = dataAdapter;
                dataAdapter = new dataAdapterConstructor();
            }            
        }
        this.dataAdapter = dataAdapter;    
        //更新数据项数据适配器.
        updateDataAdapter = updateDataAdapter || this.dataAdapter;
        if(Type.isFunction(updateDataAdapter)){
            if(updateDataAdapter.superFunction !== DataAdapter){
                var updateDataAdapterFun = updateDataAdapter;
                updateDataAdapter = new DataAdapter(updateDataAdapterFun);    
            } else {
                var dataAdapterConstructor = updateDataAdapter;
                updateDataAdapter = new dataAdapterConstructor();
            }            
        } 
        this.updateDataAdapter = updateDataAdapter;
        //内置存储.
        this.items = [];    //适配数据存储。
        this.rawItems = []; //原始数据存储。     
        this.keyItems = {}; //id索引存储。
    };
    
    //-------------------------------------------------------------------------------------------------
    
    Store.prototype.addItem = function(rawItem, isSilent){
        var item = this.dataAdapter.fun(rawItem),
            position = this.keyItems[ item[this.key] ];           
        //添加数据条目.         
        if(Type.isUndefined(position)){
            position = this.items.length;
            this.rawItems[position] = rawItem;
            this.items[position] = item;            
            this.keyItems[ item[this.key] ] = position;  
            if(isSilent !== true){         
                this.fire('addItem', item);
            }
        } 
        //若已经存在，更新数据条目.
        else {          
            this.rawItems[position] = rawItem;
            this.items[position] = item;            
            this.keyItems[ item[this.key] ] = position;
            if(isSilent !== true){        
                this.fire('updateItem', item);
            }
        }
        return this;
    };
    
    Store.prototype.updateItem = function(rawItem, isSilent){        
        var item = this.updateDataAdapter.fun(rawItem),
            position = this.keyItems[ item[this.key] ];
           
        var oldItem = this.items[position],
            newItem = $.extend(true, oldItem, item);
            
        this.items[position] = newItem;   
        if(isSilent !== true){     
            this.fire('updateItem', newItem);
        }        
        return this;
    };
    
    /**
     * 删除指定ID的数据条目. 
     * @param id {String} 数据条目ID.
     * @return {Boolean} 是否删除成功.
     */
    Store.prototype.deleteItem = function(id, isSilent){
        var position = this.keyItems[id];        
        if(Type.isUndefined(id) || Type.isUndefined(position)){
            return false;
        }
        delete this.keyItems[id];       
        
        var deletedItem = this.items[position],
            deletedRawItem = this.rawItems[position];      
              
        // this.items.removeAt(position);
        // this.rawItems.removeAt(position);
        
        this.items[position] = null;
        this.rawItems[position] = null;
        
        if(isSilent !== true){
            this.fire('deleteItem', id, deletedItem, deletedRawItem);
        }
        return true;
    };
    
    //-------------------------------------------------------------------------------------------------
    
    /**
     * 获取所有的数据条目.
     * @param isRaw {Boolean} 是否获取原始数据条目。
     * @return {Array} 
     */
    Store.prototype.getAllItems = function(isRaw){
        return isRaw === true ? this.rawItems : this.items;    
    };
    
    /**
     * 获取指定ID的数据条目.
     * @param id {String} 数据条目ID.
     * @param isRaw {Boolean} 是否获取原始数据条目。
     * @return {Mixed}
     */
    Store.prototype.getItem = function(id, isRaw){
         return (isRaw === true ? this.rawItems : this.items)[ this.keyItems[id] ];
    };
    
    /**
     * 获取指定ID的原始数据条目.
     * @param id {String} 数据条目ID.
     * @return {Mixed}
     */
    Store.prototype.getRawItem = function(id){
         return this.getItem(id , true);
    };
    
    /**
     * 获取最后添加的数据条目. 
     * @param isRaw {Boolean} 是否获取原始数据条目。
     * @return {Mixed}
     */
    Store.prototype.getLastItem = function(isRaw){
        return (isRaw === true ? this.rawItems : this.items).last();
    };
    
    //-------------------------------------------------------------------------------------------------
    
    /**
     * 清空存储器. 
     * @return this
     */
    Store.prototype.clear = function(){
        this.items = [];    
        this.keyItems = {};
        this.rawItems = [];
        return this;
    };
    
    //----------------------------------------------------------------------------------------------
    
    //TODO 老版本兼容性代码，新项目中去掉.
    global.Store = Store;
    
    ujs.define('Store', 'ujs.data', function(){
        return Store;
    });
})(window);